package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustomException;
import com.heima.feign.article.IArticleClient;
import com.heima.feign.user.IUserClient;
import com.heima.feign.wemedia.IWemediaClient;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;




@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private IArticleClient articleClient;
    @Autowired
    private IWemediaClient wemediaClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private KafkaTemplate kafkaTemplate;
    @Autowired
    private IUserClient userClient;
    /**
     * 保存评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult commentSave(CommentDto dto) {
        //1.校验参数
        if (dto == null || StringUtils.isBlank(dto.getContent()) || dto.getArticleId() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.校验文章是否可以评论
        ApArticleConfig apArticleConfig = articleClient.findById(dto.getArticleId());
        //2.1判断是否有该文章的配置
        if(apArticleConfig == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.2判断是否可以评论
        if(!apArticleConfig.getIsComment()){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论已关闭");
        }
        //3.判断是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if(apUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //4.判断评论的长度是否超过140
        if(dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论过长(最长140个字)");
        }
        //5.评论文本垃圾检测
        String comment = dto.getContent();
        ResponseResult result = wemediaClient.autoscanComment(comment);
        if(result.getCode()==501){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论违规或疑似违规");
        }
        //6.将数据添加到mongoDB中
        ApComment apComment = new ApComment();
        apComment.setAuthorId(AppThreadLocalUtil.getUser().getId());
        //远程调用用户的微服务获取用户的名字
        ApUser user = userClient.findUserById(AppThreadLocalUtil.getUser().getId());
        if(user!=null){
            apComment.setAuthorName(user.getName());
        }
        apComment.setContent(dto.getContent());
        apComment.setCreatedTime(new Date());
        apComment.setLikes(0);
        apComment.setEntryId(dto.getArticleId());
        apComment.setReply(0);
        apComment.setFlag((short)0);
        apComment.setType((short)0);
        mongoTemplate.save(apComment);
        //4. 发送消息到kafka，将文章的评论数+1
        Map<String,Object> voMap = new HashMap<>();
        voMap.put("articleId",dto.getArticleId());
        kafkaTemplate.send("comment_add", JSON.toJSONString(voMap));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1.校验参数
        if(dto == null || dto.getCommentId()==null){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if(apUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3.判断是点赞还是取消点赞
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if(apComment == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if(dto.getOperation()==0){
            //更新点赞数量
            apComment.setLikes(apComment.getLikes()+1);
            mongoTemplate.save(apComment);
            //保存点赞
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setAuthorId(apUser.getId());
            mongoTemplate.save(apCommentLike);
        }else {
            //取消点赞
            Integer likesCount = apComment.getLikes();
            if(likesCount==0){
                apComment.setLikes(0);
            }else {
                apComment.setLikes(likesCount-1);
            }
            //更新点赞数
            mongoTemplate.save(apComment);
            //删除点赞
            Query query = Query.query(Criteria.where("commentId").is(apComment.getId()).and("authorId").is(apUser.getId()));
            mongoTemplate.remove(query, ApCommentLike.class);
        }
        //4.将数据返回给前端
        Map<String, Object> result = new HashMap<>();
        result.put("likes", apComment.getLikes());
        return ResponseResult.okResult(result);
    }


    /**
     * 查询评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentDto dto) {
        //1.参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.查找符合要求的评论
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("createdTime").lt(dto.getMinDate()))
                        .with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(10);
        List<ApComment> list = mongoTemplate.find(query, ApComment.class);
        return ResponseResult.okResult(list);
    }
}
